/*
   file : lock.c
   锁模块的各个函数的实现
   University of Jiangsu
   memoryDB      2010.6
 */


#include"lock.h"
#include"def_head.h"


//管理表锁的链表
Table_lock_list *Tb_lock_list;

//表锁链表的读写锁
pthread_rwlock_t Tblist_lock; 


//系统启动时 初始化数据库锁
int Init_DB_lock()
{
   pthread_mutex_init(&fun_lock,NULL);
   return pthread_rwlock_init(&DB_lock,NULL);
}

//初始化表锁的链表 以及Tblist_lock 
int Init_tb_locklist()
{
   Tb_lock_list = malloc(sizeof(Table_lock_list));
   Init_Table_lock_list(Tb_lock_list);
   pthread_rwlock_init(&Tblist_lock,NULL);
   return 1;
}

//关闭数据库时 释放表上的锁
int Free_table_lock()
{  
   Table_lock *cur_tl = Tb_lock_list->Table_lock_list;
   Table_lock *pre_tl = NULL;
   pthread_rwlock_wrlock(&Tblist_lock);
   while(cur_tl){
     pthread_rwlock_destroy(&cur_tl->TB_lock);
     pre_tl = cur_tl;
     cur_tl = cur_tl->Next_lock;
     free(pre_tl);
   }
   pthread_rwlock_unlock(&Tblist_lock);
   return 1;
}

//关闭系统时 释放数据库的锁
int Free_DB_lock()
{ 
   pthread_mutex_destroy(&fun_lock);
   pthread_rwlock_destroy(&Tblist_lock);
   pthread_rwlock_destroy(&DB_lock);
}

////////////////////////////////////////////////////////
void Init_Table_lock(Table_lock *tl)
{
  strcpy(tl->Table_Name,"");
  tl->Next_lock = NULL;
  pthread_rwlock_init(&(tl->TB_lock),NULL);

}
void Init_Table_lock_list(Table_lock_list *tll)
{
  tll->Table_lock_list = NULL;
  tll->Last_lock = NULL;
}

int Rlock_Cur_DB()
{
	return pthread_rwlock_rdlock(&DB_lock);
}
int Wlock_Cur_DB()
{
	return pthread_rwlock_wrlock(&DB_lock);
}
int Unlock_Cur_DB()
{
	return pthread_rwlock_unlock(&DB_lock);
}

void Add_Table_lock(Table_lock *tl)
{
	pthread_rwlock_wrlock(&Tblist_lock);
	if(!(Tb_lock_list->Table_lock_list)) 
	  Tb_lock_list->Table_lock_list = tl;
	else 
	  Tb_lock_list->Last_lock->Next_lock = tl;
	
	Tb_lock_list->Last_lock = tl;
	pthread_rwlock_unlock(&Tblist_lock);
}
int Del_Table_lock(char * table_name)
{
   pthread_rwlock_wrlock(&Tblist_lock);
   Table_lock *tl = Tb_lock_list->Table_lock_list;
   Table_lock *ptl = NULL;
   for(;tl;tl = tl->Next_lock,ptl = tl){
      if(!strcmp(tl->Table_Name,table_name)){
		  if(!ptl)
			Tb_lock_list->Table_lock_list = tl->Next_lock;
		  else
			ptl->Next_lock = tl->Next_lock;
  
         pthread_rwlock_destroy(&tl->TB_lock);
         free(tl);
         return 1;
      }
   }
   pthread_rwlock_unlock(&Tblist_lock);
   return 0;
   
}

int Rlock_Table(char *table_name)
{
   pthread_rwlock_rdlock(&Tblist_lock);
   int r;
   Table_lock *tl = Tb_lock_list->Table_lock_list;
   Table_lock *ptl = NULL;
   for(;tl;tl = tl->Next_lock,ptl = tl){
      if(!strcmp(tl->Table_Name,table_name)){
		  r = pthread_rwlock_rdlock(&tl->TB_lock);
		  break;
	  }
   }
   pthread_rwlock_unlock(&Tblist_lock);
   return r;
}

int Wlock_Table(char *table_name)
{
   pthread_rwlock_rdlock(&Tblist_lock);
   int r;
   Table_lock *tl = Tb_lock_list->Table_lock_list;
   Table_lock *ptl = NULL;
   for(;tl;tl = tl->Next_lock,ptl = tl)
      if(!strcmp(tl->Table_Name,table_name)){
		  r = pthread_rwlock_wrlock(&tl->TB_lock);
		  break;
	  }
   
   pthread_rwlock_unlock(&Tblist_lock);
   return r;
}

int Unlock_Table(char *table_name)
{
   pthread_rwlock_rdlock(&Tblist_lock);
   int r;
   Table_lock *tl = Tb_lock_list->Table_lock_list;
   Table_lock *ptl = NULL;
   for(;tl;tl = tl->Next_lock,ptl = tl){
      if(!strcmp(tl->Table_Name,table_name)){
		  r = pthread_rwlock_unlock(&tl->TB_lock);
		  break;
	  }
   }
   pthread_rwlock_unlock(&Tblist_lock);
   return r;
}

void try_Unlock_Table(char *table_name)
{
   pthread_rwlock_rdlock(&Tblist_lock);
   Table_lock *tl = Tb_lock_list->Table_lock_list;
   Table_lock *ptl = NULL;
   for(;tl;tl = tl->Next_lock,ptl = tl){
      if(!strcmp(tl->Table_Name,table_name)){
		  if(pthread_rwlock_trywrlock(&tl->TB_lock))
			pthread_rwlock_unlock(&tl->TB_lock);
		  break;
	  }
   }
   pthread_rwlock_unlock(&Tblist_lock);
}
